﻿using MvcArchStarter.Core.Ioc;
using MvcArchStarter.Core.Persistence;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Text;

namespace MvcArchStarter.Infrastructure.Persistence
{
    [DependencyDiscovery(typeof(IUnitOfWork), IocLifetime.Hierarchical)]
    class MvcStarterArchContextUnitOfWork : IUnitOfWork
    {
        private DbContext _context;
        private readonly IContextFactory _factory;

        public MvcStarterArchContextUnitOfWork(IContextFactory factory)
        {
            _factory = factory;
        }
        public IRepository<TEntity> RepositoryOf<TEntity>() where TEntity : class
        {
            EnsureDbContext();
            var set = _context.Set<TEntity>();
            return new DbSetRepository<TEntity>(set);
        }

        public void SaveChanges()
        {
            if (_context != null)
                _context.SaveChanges();
        }

        public void RejectChanges()
        {
            if (_context != null)
                foreach (var entry in _context.ChangeTracker.Entries())
                {
                    if (entry.State == EntityState.Modified)
                        entry.State = EntityState.Unchanged;
                    else if (entry.State == EntityState.Added)
                        entry.State = EntityState.Detached;
                }
        }

        public bool ProxyCreationEnabled
        {
            get
            {
                return _context.Configuration.ProxyCreationEnabled;
            }
            set
            {
                _context.Configuration.ProxyCreationEnabled = value;
            }
        }

        public bool LazyLoadingEnabled
        {
            get
            {
                return _context.Configuration.LazyLoadingEnabled;
            }
            set
            {
                _context.Configuration.LazyLoadingEnabled = value;
            }
        }

        public bool AutoDetectChangesEnabled
        {
            get
            {
                return _context.Configuration.AutoDetectChangesEnabled;
            }
            set
            {
                _context.Configuration.AutoDetectChangesEnabled = value;
            }
        }

        public bool ValidateOnSaveEnabled
        {
            get
            {
                return _context.Configuration.ValidateOnSaveEnabled;
            }
            set
            {
                _context.Configuration.ValidateOnSaveEnabled = value;
            }
        }

        public void Dispose()
        {
            if (_context != null)
                _context.Dispose();
        }

        private void EnsureDbContext()
        {
            if (_context == null)
            {
                _context = _factory.Create();
                _context.Configuration.ProxyCreationEnabled = true;
                _context.Configuration.LazyLoadingEnabled = true;
                _context.Configuration.AutoDetectChangesEnabled = true;
                _context.Configuration.ValidateOnSaveEnabled = true;
            }

        }
    }
}
